package com.jwaoo.chat.data.db;

import android.content.Context;
import android.content.Intent;
import android.util.Log;

import com.dx.as.JWCache;
import com.dx.as.common.CommonUtils;
import com.dx.as.common.ILoadListener;
import com.dx.as.common.string.StringUtil;
import com.dx.as.db.IDBListener;
import com.dx.as.db.SqlLiteHelper;
import com.dx.as.upload.DownloadFile;
import com.dx.as.upload.DownloadInfo;
import com.dx.as.upload.DownloadManager;
import com.dx.as.upload.ProgressRequestBody;
import com.dx.as.upload.UploadFile;
import com.dx.as.utils.DateUtil;
import com.google.gson.Gson;
import com.jwaoo.chat.ChatConstants;
import com.jwaoo.chat.IMessageClient;
import com.jwaoo.chat.Message;
import com.jwaoo.chat.attachment.FileAttachment;
import com.jwaoo.chat.fragment.session.bean.SessionBean;
import com.jwaoo.chat.session.Extras;
import com.jwaoo.chat.session.avchat.AVChatType;
import com.jwaoo.chat.session.video.WatchVideoActivity;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

/**
 * Created by jwaoo on 2017/7/4.
 */

public class MessageHandler {
    public final static int GET_SESSION = 0;
    public final static int SAVE_SESSION = 1;
    public final static int GET_MESSAGE = 2;
    public final static int SAVE_MESSAGE = 3;
    public final static int SAVE_ALL_MESSAGE = 4;
    public final static int UPDATE_MESSAGE = 5;
    public final static int UPDATE_SESSION = 6;
    public final static int GET_MESSAGE_IMG = 7;
    public final static int DELETE_MESSAGE = 8;

    public final static int UPDATE_STATE = 0;
    public final static int UPDATE_IS_READ = 1;
    public final static int UPDATE_ATTACH_STATE = 2;

    private static MessageHandler messageHandler;
    private List<SessionBean> sessionList;
    private IMessageClient client;
    private final static Gson gson = new Gson();
    private Context mContext;
    private Map<Integer,SessionBean> sessionMap = new HashMap<>();
    private Map<Integer,Message> downloadMap = new HashMap<>();
    private MessageHandler(Context context){
        this.mContext = context;
    }

    public static synchronized MessageHandler getInstace(Context context){
        if (messageHandler == null){
            synchronized (MessageHandler.class){
                if (messageHandler == null){
                    messageHandler = new MessageHandler(context);
                }
            }
        }
        return messageHandler;
    }

    public void setIMessageClient(IMessageClient client){
        this.client = client;
    }

    public void getSessions(ChatDatabase database , ILoadListener loadListener){
        if (sessionList == null) sessionList = database.dbMsgDao().queryAllSession();
        loadListener.onResponse(sessionList,0);
    }

    public void updateSession(ChatDatabase database ,SessionBean sessionBean){
        database.dbMsgDao().updateSession(sessionBean);
    }

    private void updateMessage(ChatDatabase database,Message message){
        database.dbMsgDao().updateMessage(message);
    }

    private void deleteMessage(ChatDatabase database,Message message){
        List<Message> list = new ArrayList<>(1);
        list.add(message);
        database.dbMsgDao().deleteMessage(list);

    }

    public void saveAllSessions(ChatDatabase database ,List<SessionBean> list){
        if (sessionList == null) sessionList = database.dbMsgDao().queryAllSession();
        List<SessionBean> newSession = new ArrayList<>();
        List<SessionBean> updateSession = new ArrayList<>();
        if (sessionMap.isEmpty()){
            for (SessionBean sessionBean : sessionList){
                sessionMap.put(sessionBean.getFriend(),sessionBean);
            }
        }
        for (SessionBean sessionBean : list){
            if (sessionMap.containsKey(sessionBean.getFriend())){
                int msgType = sessionBean.getMsgtype();
                String msg = sessionBean.getMsg();
                long timestamp = sessionBean.getTimestamp();
                int count = sessionBean.getCount();
                int sessionType = sessionBean.getSessionType();
                sessionMap.get(sessionBean.getFriend()).setMsgtype(msgType);
                sessionMap.get(sessionBean.getFriend()).setMsg(msg);
                sessionMap.get(sessionBean.getFriend()).setTimestamp(timestamp);
                sessionMap.get(sessionBean.getFriend()).setCount(sessionMap.get(sessionBean.getFriend()).getCount() + count);
                sessionMap.get(sessionBean.getFriend()).setSessionType(sessionType);
                updateSession.add(sessionMap.get(sessionBean.getFriend()));
            }else {
                sessionMap.put(sessionBean.getFriend(),sessionBean);
                newSession.add(sessionBean);
            }
        }
        database.dbMsgDao().updateAllSession(updateSession);
        if (newSession.size() > 0) {
            sessionList.addAll(newSession);
            database.dbMsgDao().insertALLSession(list);
        }

    }

    public void getMessages(ChatDatabase database,String uuid,long time ,ILoadListener loadListener){
        List<Message> list = null;
        if (time == 0)
                list = database.dbMsgDao().queryMessage(uuid);
        else
            list = database.dbMsgDao().queryMessage(uuid,time);
        loadListener.onResponse(list,0);
    }

    public void getMessagesWithIMG(ChatDatabase database,int friend,ILoadListener loadListener){
        List<Message> list = null;
        list = database.dbMsgDao().queryMessageWithIMG(friend,ChatConstants.image);
        loadListener.onResponse(list,0);
    }

    public void saveMessage(ChatDatabase database,Message message){
        database.dbMsgDao().insertMessage(message);
//        if (message.getMsgtype() == ChatConstants.audio){
//            handlerAttachmentMessage(message);
//        }
    }

    public void saveAllMessage(ChatDatabase database,List<Message> messages){
        database.dbMsgDao().insertALLMessage(messages);
    }

    /**
     * 第一个参数 ： what 执行的操作
     * 第二个参数 ：
     * @param objects
     */
    public void handlerMessages(final Object ... objects){
        SqlLiteHelper.getInstance(mContext).dbOption(ChatDatabase.class,new IDBListener<ChatDatabase>(){
            @Override
            public void onOption(ChatDatabase database) {
                int what = Integer.valueOf(objects[0].toString());
                switch (what){
                    case GET_SESSION:
                        ILoadListener loadListener = (ILoadListener) objects[1];
                        getSessions(database,loadListener);
                        break;
                    case SAVE_SESSION:
                        List<SessionBean> sessionBeanList = (List<SessionBean>) objects[1];
                        saveAllSessions(database,sessionBeanList);
                        break;
                    case GET_MESSAGE:
                        String uuid = objects[1].toString();
                        ILoadListener loadListenerMsg = (ILoadListener) objects[2];
                        long time = (Long) objects[3];
                        getMessages(database,uuid,time,loadListenerMsg);
                        break;
                    case SAVE_MESSAGE:
                        Message message = (Message) objects[1];
                        saveMessage(database,message);
                        break;
                    case SAVE_ALL_MESSAGE:
                        List<Message> messageList = (List<Message>) objects[1];
                        saveAllMessage(database,messageList);
                        break;
                    case UPDATE_MESSAGE:
                        Message message1 = (Message) objects[1];
                        updateMessage(database,message1);
                        break;
                    case UPDATE_SESSION:
                        SessionBean sessionBean = (SessionBean) objects[1];
                        updateSession(database,sessionBean);
                        break;
                    case GET_MESSAGE_IMG:
                        int friend = Integer.parseInt(objects[1].toString());
                        ILoadListener iLoadListener = (ILoadListener) objects[2];
                        getMessagesWithIMG(database,friend,iLoadListener);
                        break;
                    case DELETE_MESSAGE:
                        Message message2 = (Message) objects[1];
                        deleteMessage(database,message2);
                        break;
                }
            }
        });
    }

    //拉取离线消息
    public void unLineMessage(){

    }

    public String getMsgJson(Message message){
       return gson.toJson(message);
    }

    public boolean sendMessage(Message message){
        String json = createJson(message);
         return this.client.sendMessage(message,json);
    }

    public Message createMessage(Object ... objects) {
        Message message = getBaseMessage();
        int msgType = Integer.parseInt(objects[0].toString());
        int friend = Integer.parseInt(objects[1].toString());
        switch (msgType){
            case ChatConstants.text:
            case ChatConstants.audio_chat:
            case ChatConstants.video_chat:
                String content = objects[2].toString();
                message.setMsg(content);
                break;
            case ChatConstants.audio:
            case ChatConstants.video:
            case ChatConstants.image:
            case ChatConstants.snap:
                FileAttachment fileAttachment = (FileAttachment)objects[2];
                message.setAttachment(fileAttachment);
                message.setState(ChatConstants.sending);
                message.setAttachState(ChatConstants.transferring);
                break;
            default:
                break;
        }
        message.setMsgtype(msgType);
        message.setFriend(friend);
        handlerMessages(SAVE_MESSAGE,message);
        return message;
    }

    private Message getBaseMessage(){
        Message message = new Message();
        int _id = (int)System.currentTimeMillis();
        message.set_id(_id);
        message.setState(ChatConstants.sending);
        message.setSessionType(1);
        message.setDirect(ChatConstants.Out);
        message.setTimestamp(DateUtil.getUnixTimeByCalendar());
        return message;
    }

    private String createJson(Message message){
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("{");
        stringBuffer.append("\"sessionType\":");
        stringBuffer.append(message.getSessionType());
        stringBuffer.append(",");
        stringBuffer.append("\"timestamp\":");
        stringBuffer.append(message.getTimestamp());
        stringBuffer.append(",");
        stringBuffer.append("\"msgtype\":");
        stringBuffer.append(message.getMsgtype());
        stringBuffer.append(",");
        stringBuffer.append("\"msg\":");
        stringBuffer.append("\""+message.getMsg()+"\"");
        if (message.getMsgtype() == ChatConstants.text || message.getMsgtype() == ChatConstants.audio_chat || message.getMsgtype() == ChatConstants.video_chat) {
            stringBuffer.append("}");
            return stringBuffer.toString();
        }
        stringBuffer.append(",");
        stringBuffer.append("\"attachment\":");
        stringBuffer.append("{");
        stringBuffer.append("\"url\":");
        stringBuffer.append("\""+message.getAttachment().getUrl()+"\"");
        if (message.getMsgtype() == ChatConstants.audio){
            stringBuffer.append(",");
            stringBuffer.append("\"length\":");
            stringBuffer.append(message.getAttachment().getLength());
            stringBuffer.append("}}");
            return stringBuffer.toString();
        }
        stringBuffer.append(",");
        stringBuffer.append("\"thumbnail\":");
        stringBuffer.append("\""+message.getAttachment().getThumbnail()+"\"");
        if (message.getMsgtype() == ChatConstants.image ){
            stringBuffer.append("}}");
            return stringBuffer.toString();
        }
        if (message.getMsgtype() == ChatConstants.video || message.getMsgtype() == ChatConstants.snap){
            stringBuffer.append(",");
            stringBuffer.append("\"size\":");
            stringBuffer.append(message.getAttachment().getSize());
            stringBuffer.append(",");
            stringBuffer.append("\"height\":");
            stringBuffer.append(message.getAttachment().getHeight());
            stringBuffer.append(",");
            stringBuffer.append("\"width\":");
            stringBuffer.append(message.getAttachment().getWidth());
            stringBuffer.append("}}");
            return stringBuffer.toString();
        }
        return "";
    }

    public void uploadAttachmentMessage(final Message message){
        final Map<String,Object> parm = new HashMap<>();
        parm.put("as","pub");
        parm.put("flag","zoom");
        if (message.getMsgtype() == ChatConstants.video){
            parm.put("type","video");
            parm.put("end",".mp4");
            parm.put("media_type","video/mp4");
            File file = new File(message.getAttachment().getPath());
            doUpload(file,message,parm);

            File file1 = new File(message.getAttachment().getThumbnail());
            message.getAttachment().setThumbnail("");
            parm.put("type","img");
            parm.put("end",".jpg");
            parm.put("media_type","image/jpg");
            doUpload(file1,message,parm);
        }else if (message.getMsgtype() == ChatConstants.image || message.getMsgtype() == ChatConstants.snap){
            File file1 = new File(message.getAttachment().getPath());
            message.getAttachment().setThumbnail("");
            parm.put("type","img");
            parm.put("end",".jpg");
            parm.put("media_type","image/jpg");
            doUpload(file1,message,parm);
        }
        downloadMap.put(message.get_id(),message);
    }

    private void doUpload(File file,final Message message,Map<String,Object> parm){

        DownloadInfo downloadInfo = new DownloadInfo(){
            @Override
            public void onDownLoadSuccess() {
                super.onDownLoadSuccess();
                handlerMessages(UPDATE_MESSAGE,downloadMap.get(this.getMsgId()));
            }

            @Override
            public void onDownLoadFailed() {
                super.onDownLoadFailed();
                downloadMap.get(this.getMsgId()).setAttachState(ChatConstants.fail);
                handlerMessages(UPDATE_MESSAGE,downloadMap.get(this.getMsgId()));
//                    sendUpdateMessageBroad(downloadMap.get(this.msgId));
            }

            @Override
            public void onDownProgress(long progress, long total) {
                super.onDownProgress(progress, total);
            }

            @Override
            public int getMsgId() {
                return message.get_id();
            }
        };

        UploadFile.uploadFile(parm,file , new ILoadListener() {
            @Override
            public void onResponse(Object response, int flg) {
                if (response != null){
                    Map<String,String> result = (Map<String, String>) response;
                    String url = result.get("path");
                    if (message.getMsgtype() == ChatConstants.video || message.getMsgtype() == ChatConstants.image){
                        if (result.containsKey("smallPath")) {
                            message.getAttachment().setThumbnail(result.get("smallPath"));
                            if (message.getMsgtype() == ChatConstants.image){
                                message.setAttachState(ChatConstants.transferred);
                                message.getAttachment().setUrl(url);
                            }
                        }else {
                            message.setAttachState(ChatConstants.transferred);
                            message.getAttachment().setUrl(url);
                        }
                        if (!StringUtil.isEmpty(message.getAttachment().getUrl()) && !StringUtil.isEmpty(message.getAttachment().getThumbnail())){
                            sendMessage(message);
                            return;
                        }
                    }else{
                        message.setAttachState(ChatConstants.transferred);
                        message.getAttachment().setUrl(url);
                        sendMessage(message);
                    }
                }
            }

            @Override
            public void onFailure(Throwable t) {
                message.setAttachState(ChatConstants.fail);
                handlerMessages(UPDATE_MESSAGE,message);
//                messageListPanel.refreshMessageList(message);
            }
        },new ProgressRequestBody(file,message.get_id(),downloadInfo));
        downloadMap.put(message.get_id(),message);
    }


    public void handlerAttachmentMessage(final Message message){
        if (StringUtil.isEmpty(message.getAttachment().getPath())){
            String dir = "";
            if (message.getMsgtype() == ChatConstants.audio){
                dir = CommonUtils.getAudioDir(mContext);
            }else if (message.getMsgtype() == ChatConstants.video){
                dir = CommonUtils.getVideoDir(mContext);
            }else if (message.getMsgtype() == ChatConstants.image || message.getMsgtype() == ChatConstants.snap){
                dir = CommonUtils.getImgDir(mContext);
            }
            DownloadInfo downloadInfo = new DownloadInfo(){
                @Override
                public void onDownLoadSuccess() {
                    super.onDownLoadSuccess();
                    handlerMessages(UPDATE_MESSAGE,downloadMap.get(this.getMsgId()));
                }

                @Override
                public void onDownLoadFailed() {
                    super.onDownLoadFailed();
                    downloadMap.get(this.getMsgId()).setAttachState(ChatConstants.fail);
                    handlerMessages(UPDATE_MESSAGE,downloadMap.get(this.getMsgId()));
//                    sendUpdateMessageBroad(downloadMap.get(this.msgId));
                }

                @Override
                public void onDownProgress(long progress, long total) {
                    super.onDownProgress(progress, total);
                }

                @Override
                public int getMsgId() {
                    return message.get_id();
                }
            };

            String path = getFilePath(dir,message.getAttachment().getUrl());
            message.getAttachment().setPath(path);
            message.setAttachState(ChatConstants.transferred);
            downloadMap.put(message.get_id(),message);
            new DownloadFile().doDownLoad(message.get_id(),message.getAttachment().getUrl(),path,downloadInfo);
        }
    }

    private String getFilePath(String dir,String url){
        if (StringUtil.isEmpty(url)) return null;
        return dir + url.substring(url.lastIndexOf("/")+1,url.lastIndexOf(".")-1);
    }
    private void sendUpdateMessageBroad(Message message){
        Intent intentMessage = new Intent();
        intentMessage.setAction(ChatConstants.ACTION_MESSAGE);
        intentMessage.putExtra(Extras.EXTRA_MESSAGE,message);
        JWCache.getContext().sendBroadcast(intentMessage);
    }
}
